/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package manager;

import entity.AbstractEntity;
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.Query;

/**
 * Default manager gives any inheriting class CRUD operations already implemented , along with other functions like
 * finding by primary key and works with AbstractEntity to give logical delete and versioning. It is to be inherited by individual managers that implement additional functions needed to
 * give functionality to application.
 * @param <T> Class That extends AbstractEntity for witch the manager will be implemented
 * @author Stefan Martinov <stefan.martinov@gmail.com>
 */
public class DefaultManager<T extends AbstractEntity> implements Serializable {

    private static final EntityManagerFactory emf = Persistence.createEntityManagerFactory("EvInPU");
    protected static EntityManager em = emf.createEntityManager();

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }
    private Class<T> entityType;

    public DefaultManager(Class<T> cl) {
        entityType = cl;
    }

    public T create(T entity) {
        EntityTransaction et = null;
        et = em.getTransaction();
        if (em.getTransaction().isActive()) {
            em.getTransaction().rollback();
        }
        et.begin();

        em.persist(entity);

        et.commit();
        return entity;
    }

    public T edit(T entity) {
        EntityTransaction et = null;
        et = em.getTransaction();
        if (em.getTransaction().isActive()) {
            em.getTransaction().rollback();
        }

        et.begin();

        entity = em.merge(entity);

        et.commit();
        return entity;

    }

    public void remove(T entity) {
        EntityTransaction et = null;
        et = em.getTransaction();
        if (em.getTransaction().isActive()) {
            em.getTransaction().rollback();
        }

        et.begin();
        entity.setDeleted(true);
        em.merge(entity);

        et.commit();
    }

    public T findByID(Long id) {
        T entity;
        entity = em.find(entityType, id);
        return entity;
    }

    public List<T> findAll() {
        Query q = em.createQuery("SELECT x FROM " + entityType.getSimpleName() + " x WHERE x.deleted = false");
        List<T> result = q.getResultList();
        return result;
    }
}
